# -*- coding: utf-8 -*-
"""
Created on Thu Jan 03 01:53:25 2013

@author: Winand
"""

#%(module)s/%(funcName)s/%(lineno)d
import inspect, os, sys
from logging import debug as dbg, info as inf, warn as wrn, error as err, fatal as ftl
from settings import LOG_LEVEL, LOGFILE, LOG_TO_CONSOLE, SHARED_SERVER_ADDR, SHARED_SERVER_PORT
import logging, logging.handlers
from webapi.server.socketpipe import SocketPipe

def __genLogWrapper(f):
    def logwith(*l):
        calframe = inspect.getouterframes(inspect.currentframe())
        if len(calframe)>1:
            frame=calframe[1]
            mod=os.path.splitext(os.path.basename(frame[1]))[0]
            func="."+frame[3] if frame[3] != "<module>" else ""
        f(" ".join([str(i) for i in (mod+func+":"+str(frame[2])+">\n",)+l]))
    return logwith
    
def __genRemoteLogger(lvl):
    def logwith(*l):
        calframe = inspect.getouterframes(inspect.currentframe())
        if len(calframe)>1:
            frame=calframe[1]
            mod=os.path.splitext(os.path.basename(frame[1]))[0]
            func="."+frame[3] if frame[3] != "<module>" else ""

        sockpipe = SocketPipe()
        try:
            sockpipe.connect(SHARED_SERVER_ADDR, SHARED_SERVER_PORT, timeout=0.3)
            sockpipe.send(("log", lvl, " ".join([str(i) for i in (mod+func+":"+str(frame[2])+">\n",)+l])))
        except: pass
        finally: sockpipe.close()
    return logwith

#Client logs collector (server request handler)
LVL_FNC = {}
def remoteLogHandler(data_pipe, lvl, s):
    LVL_FNC[lvl](s)

#Log info and above levels to file
def enableOutputToFile(filename):
    size=256*1024 #KB
    handler=logging.handlers.RotatingFileHandler(filename, maxBytes=size, backupCount=1)
    handler.setFormatter(logging.Formatter('%(levelname)s %(asctime)s %(message)s', datefmt='%d %b %H:%M:%S'))
    logger=logging.getLogger()
    logger.setLevel(LOG_LEVEL)
    logger.addHandler(handler)

#Log everything to console
def enableOutputToConsole():
    logging.basicConfig(stream=sys.stdout, level=LOG_LEVEL, \
    format='%(levelname)s %(asctime)s %(message)s', \
    datefmt='%H:%M:%S') #output to stderr

def InitLocalLogging():
    #Init logging
    #Redefine built-in log level names
    map(logging.addLevelName, [logging.DEBUG, logging.INFO, logging.WARN, \
                        logging.ERROR, logging.FATAL], ["D", "I", "W", "E", "F"])
                        
    global debug, info, warn, error, fatal, LVL_FNC
    debug, info, warn, error, fatal=map(__genLogWrapper, [dbg, inf, wrn, err, ftl])
    LVL_FNC = {logging.DEBUG: debug, logging.INFO: info, logging.WARN: warn,
                                   logging.ERROR: error, logging.FATAL: fatal}
    
    #ENABLING LOGGING FEATURES
    if LOG_TO_CONSOLE: enableOutputToConsole()
    enableOutputToFile(LOGFILE) #output logs to file
    
#By default server-side logger is activated
#Server uses InitLocalLogging() to log locally
debug, info, warn, error, fatal=map(__genRemoteLogger, [logging.DEBUG, \
        logging.INFO, logging.WARN, logging.ERROR, logging.FATAL])
